package gitee.derumin.lib_for_derumin.commands;

import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import gitee.derumin.lib_for_derumin.commands.suggestionproviders.AnnounceTypeSuggestionProvider;
import gitee.derumin.lib_for_derumin.logger.DeruminLogger;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.server.command.CommandManager;
import net.minecraft.text.Text;

import java.util.List;

public class DeruminLoggerCommand {
    private static final DeruminLogger LOGGER = DeruminLogger.getLogger();

    public static void register(){
        CommandRegistrationCallback.EVENT.register(((dispatcher, registryAccess, environment) -> dispatcher.register(CommandManager.literal("deruminlogger")
                .requires(serverCommandSource -> serverCommandSource.hasPermissionLevel(2))
                .then(CommandManager.literal("savelogs")
                        .executes(context -> {
                            LOGGER.saveLogsImmediately(null, true);
                            context.getSource().sendFeedback(() -> Text.of("Tried to save logs to file: (default name).log"), true);
                            return 1;
                        })
                        .then(CommandManager.argument("filename", StringArgumentType.string())
                                .executes(context -> {
                                    String fileName = StringArgumentType.getString(context, "filename");
                                    LOGGER.saveLogsImmediately(fileName, false);
                                    context.getSource().sendFeedback(() -> Text.of("Tried to save logs to file: " + fileName + ".log"), true);
                                    return 1;
                                })))
                .then(CommandManager.literal("getlogs")
                        .executes(context -> {
                            List<String> output = LOGGER.getRecentLogs(20);
                            output.forEach(s -> context.getSource().sendFeedback(() -> Text.of(s), false));
                            return output.size();
                        })
                        .then(CommandManager.argument("quantity", IntegerArgumentType.integer())
                                .executes(context -> {
                                    int quantity = IntegerArgumentType.getInteger(context, "quantity");
                                    if (quantity <= 0){
                                        context.getSource().sendFeedback(() -> Text.of("Failed to get logs: the argument must be positive!"), false);
                                        return 0;
                                    }else {
                                        List<String> output = LOGGER.getRecentLogs(quantity);
                                        output.forEach(s -> context.getSource().sendFeedback(() -> Text.of(s), false));
                                        return output.size();
                                    }})))
                .then(CommandManager.literal("log")
                        .then(CommandManager.literal("error")
                                .then(CommandManager.argument("announcetype", StringArgumentType.string())
                                        .suggests(AnnounceTypeSuggestionProvider.PROVIDER)
                                        .then(CommandManager.argument("contents", StringArgumentType.string())
                                                .executes(context -> {
                                                    DeruminLogger.AnnounceType type;
                                                    try {
                                                        type = DeruminLogger.AnnounceType.valueOf(StringArgumentType.getString(context, "announcetype"));
                                                    }catch (IllegalArgumentException e){
                                                        return 0;
                                                    }
                                                    LOGGER.error("From " + context.getSource().getName() + ":" + StringArgumentType.getString(context, "contents"), type);
                                                    return 1;
                                                }))))
                        .then(CommandManager.literal("warn")
                                .then(CommandManager.argument("announcetype", StringArgumentType.string())
                                        .suggests(AnnounceTypeSuggestionProvider.PROVIDER)
                                        .then(CommandManager.argument("contents", StringArgumentType.string())
                                                .executes(context -> {
                                                    DeruminLogger.AnnounceType type;
                                                    try {
                                                        type = DeruminLogger.AnnounceType.valueOf(StringArgumentType.getString(context, "announcetype"));
                                                    }catch (IllegalArgumentException e){
                                                        return 0;
                                                    }
                                                    LOGGER.warn("From " + context.getSource().getName() + ":" + StringArgumentType.getString(context, "contents"), type);
                                                    return 1;
                                                }))))
                        .then(CommandManager.literal("info")
                                .then(CommandManager.argument("announcetype", StringArgumentType.string())
                                        .suggests(AnnounceTypeSuggestionProvider.PROVIDER)
                                        .then(CommandManager.argument("contents", StringArgumentType.string())
                                                .executes(context -> {
                                                    DeruminLogger.AnnounceType type;
                                                    try {
                                                        type = DeruminLogger.AnnounceType.valueOf(StringArgumentType.getString(context, "announcetype"));
                                                    }catch (IllegalArgumentException e){
                                                        return 0;
                                                    }
                                                    LOGGER.info("From " + context.getSource().getName() + ":" + StringArgumentType.getString(context, "contents"), type);
                                                    return 1;
                                                }))))
                        .then(CommandManager.literal("record")
                                .then(CommandManager.argument("contents", StringArgumentType.string())
                                        .executes(context -> {
                                            LOGGER.record("From " + context.getSource().getName() + ":" + StringArgumentType.getString(context, "contents"));
                                            return 1;
                                        }))))
        )));
    }
}
